import * as util from "./util";
import _ from "lodash";

export default new class {
    get4Direction(x, y) {
        let up = {
            x,
            y: y + 1,
        };
        let down = {
            x,
            y: y - 1,
        };
        let left = {
            x: x - 1,
            y,
        };
        let right = {
            x: x + 1,
            y,
        };
        return {up, down, left, right};
    }

    combine(x, y, string, board, isBlack) {
        console.log("开始combine")
        //关联的四个方向
        let {up, down, left, right} = this.get4Direction(x, y)

        let su = this.getStringInfo(up.x, up.y, board, string, isBlack);
        let sd = this.getStringInfo(down.x, down.y, board, string, isBlack);
        let sl = this.getStringInfo(left.x, left.y, board, string, isBlack);
        let sr = this.getStringInfo(right.x, right.y, board, string, isBlack);
        if (
            (su === false || su === -1) &&
            (sd === false || sd === -1) &&
            (sl === false || sl === -1) &&
            (sr === false || sr === -1)
        ) {
            //在单个棋串中添加元素
            let stringNum = string.num;
            let subString;
            if (isBlack) {
                subString = string.black;
            } else {
                subString = string.white;
            }
            if (!subString[x]) {
                subString[x] = {};
            }
            if (!subString[stringNum]) {
                subString[stringNum] = [];
            }
            subString[x][y] = stringNum;
            subString[stringNum].push({x, y});
            string.num++;
        } else {
            let src = this.getSrcString(su, sd, sl, sr);
            console.log("基准棋串为 :>> ", src);
            string = this.combineCurrentString(x, y, su, sd, sl, sr, src, isBlack, string, board);
        }
        return string;
    }

    //合并目前的棋串
    combineCurrentString(x, y, su, sd, sl, sr, src, isBlack, string, board) {
        console.log(
            "combineCurrentString:x,y,su,sd,sl,sr,src :>> ",
            x,
            y,
            su,
            sd,
            sl,
            sr,
            src
        );
        let subString = null;
        console.log("combineCurrentString string->", string)
        if (isBlack) {
            subString = string.black;
        } else {
            subString = string.white;
        }
        //先把新的棋子加进去 需要考虑加的棋子原本横坐标不存在的情况
        if (!subString[x]) {
            subString[x] = {};
        }
        subString[x][y] = src;
        subString[src].push({x, y});

        //有其他串
        if (su > 0 && su !== src) {
            console.log("合并su :>> ", su);
            subString[src] = subString[src].concat(subString[su]);

            for (let key in subString) {
                //只考虑棋子 子串自己会删除
                if (key < 19) {
                    for (let subKey in subString[key]) {
                        if (subString[key][subKey] === su) {
                            subString[key][subKey] = src;
                        }
                    }
                }
            }
            delete subString[su];
        }
        //有其他串
        if (sd > 0 && sd !== src) {
            console.log("合并sd :>> ", sd);

            subString[src] = subString[src].concat(subString[sd]);
            for (let key in subString) {
                if (key < 19) {
                    for (let subKey in subString[key]) {
                        if (subString[key][subKey] === sd) {
                            subString[key][subKey] = src;
                        }
                    }
                }
            }
            delete subString[sd];
        }
        if (sl > 0 && sl !== src) {
            console.log("合并sl :>> ", sl);
            subString[src] = subString[src].concat(subString[sl]);
            for (let key in subString) {
                if (key < 19) {
                    for (let subKey in subString[key]) {
                        //不一样的别合并
                        if (subString[key][subKey] === sl) {
                            subString[key][subKey] = src;
                        }
                    }
                }
            }
            delete subString[sl];
        }
        if (sr > 0 && sr !== src) {
            console.log("合并sr :>> ", sr);
            subString[src] = subString[src].concat(subString[sr]);
            for (let key in subString) {
                if (key < 19) {
                    for (let subKey in subString[key]) {
                        if (subString[key][subKey] === sr) {
                            subString[key][subKey] = src;
                        }
                    }
                }
            }
            delete subString[sr];
        }
        return string
    }

    //获取一个基准棋串
    getSrcString(su, sd, sl, sr) {
        if (su > 0) {
            return su;
        }
        if (sd > 0) {
            return sd;
        }
        if (sl > 0) {
            return sl;
        }
        if (sr > 0) {
            return sr;
        }
    }


    getStringInfo(x, y, board, string, isBlack) {
        //越界 刚才的点在边界
        if (x < 0 || x > 18 || y < 0 || y > 18) {
            return -1;
        }
        // 目前是黑在下 但这个点返回的是空或者白
        if (board[x][y] !== (isBlack ? 1 : -1)) {
            return false;
        } else {
            let subString = null;
            if (isBlack) {
                subString = string.black;
            } else {
                subString = string.white;
            }
            //存在这个棋串
            if (subString[x] && subString[x][y]) {
                //获取棋串编号
                return subString[x][y];
            } else {
                // true就是这个点是新增的棋串
                return true;
            }
        }
    }

    // 判断在这个点落子后 是否可以杀棋
    kill(x, y, flag, string, board) {
        //关联的四个方向
        let {up, down, left, right} = this.get4Direction(x, y);
        let killed = [];
        //在棋盘内的才有看的必要
        if (up.x >= 0 && up.x < 19 && up.y >= 0 && up.y < 19) {
            if (board[up.x][up.y] === flag) {
                let res = this.checkKill(up.x, up.y, flag, string, board);
                if (res !== false) {
                    killed.push(res);
                }
            }
        }
        if (down.x >= 0 && down.x < 19 && down.y >= 0 && down.y < 19) {
            if (board[down.x][down.y] === flag) {
                let res = this.checkKill(down.x, down.y, flag, string, board);
                if (res !== false) {
                    killed.push(res);
                }
            }
        }
        if (right.x >= 0 && right.x < 19 && right.y >= 0 && right.y < 19) {
            if (board[right.x][right.y] === flag) {
                let res = this.checkKill(right.x, right.y, flag, string, board);
                if (res !== false) {
                    killed.push(res);
                }
            }
        }
        if (left.x >= 0 && left.x < 19 && left.y >= 0 && left.y < 19) {
            if (board[left.x][left.y] === flag) {
                let res = this.checkKill(left.x, left.y, flag, string, board);
                if (res !== false) {
                    killed.push(res);
                }
            }
        }
        return killed;
    }

    //判断这个点所在棋串是否是死棋 false-活棋 num-死棋的棋串编号
    checkKill(x, y, flag, string, board) {
        let color = flag === 1 ? "black" : "white";
        let subString = string[color];
        let num = subString[x][y];
        let arr = subString[num];
        console.log("判断这个棋串 num,arr:>> ", num, arr);
        for (let i = 0; i < arr.length; i++) {
            let x = arr[i].x;
            let y = arr[i].y;
            //关联的四个方向
            let {up, down, left, right} = util.get4Direction(x, y);

            if (up.x >= 0 && up.x < 19 && up.y >= 0 && up.y < 19) {
                if (board[up.x][up.y] === 0) {
                    return false;
                }
            }
            if (down.x >= 0 && down.x < 19 && down.y >= 0 && down.y < 19) {
                if (board[down.x][down.y] === 0) {
                    return false;
                }
            }
            if (left.x >= 0 && left.x < 19 && left.y >= 0 && left.y < 19) {
                if (board[left.x][left.y] === 0) {
                    return false;
                }
            }
            if (right.x >= 0 && right.x < 19 && right.y >= 0 && right.y < 19) {
                if (board[right.x][right.y] === 0) {
                    return false;
                }
            }
        }
        return num;
    }


    //确定这个棋串被杀死后，清除
    cleanString(num, string, board) {
        let flag = null;
        if (string.black[num]) {
            flag = "black";
        } else {
            flag = "white";
        }
        console.log("要杀死的棋串为 :>> ", num);

        let killed = [];
        let arr = string[flag][num];
        console.log("arr :>> ", arr);
        //避免重复杀棋导致错误
        if (!arr) {
            console.log("num 已被杀死 :>> ");
            return {
                killed,
                board,
                string
            };
        }
        for (let i = 0; i < arr.length; i++) {
            let x = arr[i].x;
            let y = arr[i].y;

            delete string[flag][x][y];
            if (_.isEmpty(string[flag][x])) {
                delete string[flag][x];
            }
            board[x][y] = 0;
            killed.push({x, y});
        }
        delete string[flag][num];
        return {
            killed,
            string,
            board
        };
    }
}
